#include "Nain.h"

using namespace std;
using namespace boost::assign;

const unsigned int Nain::ens = 4;

const unsigned int Nain::nbr_comp = 5;

const vector< vector< unsigned int > > Nain::ensemble_racial =
  list_of< vector< unsigned int> >
  ( list_of(13)( 1)( 2)( 4) )      // collines
  ( list_of(13)( 1)( 2)( 4) )      // montagnes
  ( list_of(13)( 1)( 2)( 4) )      // profondeurs
  ( list_of(13)( 1)( 4)( 2)(11) ); // gris

const unsigned int Nain::taille = 28;

/**
 * Contient les capacités, puis les ensembles raciaux, à la fin.
 */
const vector< ListCapa > Nain::Liste = list_of
  (ListCapa("Bonus au contact"                  , 10))
  (ListCapa("Bonus au JS"                       , 10))
  (ListCapa("Brasseur"                          ,  5))
  (ListCapa("Détection des poisons"             ,  5))
  (ListCapa("Détection minière"                 , 10))
  (ListCapa("Détermination de l'ancienneté"     ,  5))
  (ListCapa("Analyse de stabilité"              ,  5))
  (ListCapa("Evaluation des gemmes"             ,  5))
  (ListCapa("Expert en marchandage"             ,  5))
  (ListCapa("Force augemntée"                   , 20))
  (ListCapa("Furtivité"                         , 10))
  (ListCapa("Fusion dans la pierre"             , 10))
  (ListCapa("Infravision"                       , 10))
  (ListCapa("Lien chthonien"                    ,  5))
  (ListCapa("Massif"                            , 10))
  (ListCapa("Pierres commères"                  , 10))
  (ListCapa("Résistant"                         , 10))
  (ListCapa("Résistance à l'illusion"           ,  5))
  (ListCapa("Talent pour les arbalètes"         ,  5))
  (ListCapa("Talent pour les épées courtes"     ,  5))
  (ListCapa("Talent pour les haches"            ,  5))
  (ListCapa("Talent pour les marteaux de guerre",  5))
  (ListCapa("Talent pour les masses"            ,  5))
  (ListCapa("Talent pour les pics"              ,  5))
  (ListCapa("Nain des Collines"                 , 40))
  (ListCapa("Nain des Montagnes"                , 40))
  (ListCapa("Nain des Profondeurs"              , 45))
  (ListCapa("Nain Gris"                         , 45));

/**
 * Constructeur simplifié, qui remplit simplement le conteneur des capacités.
 * Il est utilisé lors de la lecture d'un fichier XML.
 * @param cap conteneur des capacité
 */
Nain::Nain(vector<unsigned int> cap)
  :Race("Nain")
{
  ptrCapa    = &Liste;
  ptrNbrCapa = &taille;
  ptrEns     = &ensemble_racial;
  ptrNbrEns  = &ens;
  ptrMaxEns   = &nbr_comp;

  for (unsigned int i(0); i < cap.size(); i++)
    capacites.push_back(cap[i]);
}

/**
 * Constructeur usuel, qui permet de créer un Nain en sélectionnant
 * ses capacités.
 * @param PP nombre de pp, passé en argument afin de pouvoir récupéré les
 * pp non dépensé
 */
Nain::Nain(unsigned int& PP)
  :Race("Nain")
{
  ptrCapa    = &Liste;
  ptrNbrCapa = &taille;
  ptrEns     = &ensemble_racial;
  ptrNbrEns  = &ens;
  ptrMaxEns   = &nbr_comp;

  blank() << setfill('*') << setw(56) << '*' << endreq;
  blank() << "Création d'un nain" << endl << endreq;
  
  unsigned int nbr(0);
  bool test(true), deja_pris, encore(false);
  PP = 45;
  do
    {
      blank() << "Tu as 45 pp à dépenser" << endreq;
      for (unsigned int i(0); i<taille; i++)
	blank() << i+1 << ' ' << Liste[i].Capa << " (" << Liste[i].Cout
		    << " pp)" << endreq;
      blank() << taille+1 << " Aucune" << endreq;
      blank() << "Choisir les capacités raciales" << endreq;
      while(test)
	{
	  nbr = demander_unsigned_borne("("+write_int(PP)+" pp restants ",
					1, taille + 1);
	  if (nbr == taille+1)
	    test = false;
	  else
	    {
	      if (PP >= Liste[nbr-1].Cout)
		{
		  PP -= Liste[nbr-1].Cout;
		  if (nbr<24)
		    {
		      deja_pris = safe_push_back(&capacites, nbr - 1);
		      if (deja_pris)
			warning() << "Déjà sélectionné" << endreq;
		      else
			{
			  capacites.push_back(nbr-1);
			  blank() << "Capacité choisie : " << Liste[nbr-1].Capa
				      << endreq;
			}
		    }
		  else
		    {
		      blank() << "Achat de l'ensemble racial : "
				  << Liste[nbr-1].Capa << endreq;
		      for (unsigned int i(0); i < nbr_comp; i++)
			{
			  if (ensemble_racial[nbr-25][i] != 0)
			    capacites.push_back(ensemble_racial[nbr-25][i]-1);
			}
		    }
		}
	      else
		blank() << "Pas assez de pp" << endreq;
	    }
	}
      
      affiche_info();
      blank() << endl <<  "1 pour continuer, 2 pour recommencer" << endreq;
      nbr = demander_unsigned_borne("Choix ", 1, 2);
      if (nbr == 2)
	{
	  PP = 45;
	  capacites.clear();
	  test = true;
	  encore = true;
	  blank() << endreq;
	}
      else
	encore = false;
    }
  while(encore);
  
  blank() << endl << setfill('*') << setw(56) << '*' << endreq;
}

Nain::Nain()
  :Race("Nain")
{}

/**
 * Destructeur, ne fait rien de spécial.
 */
Nain::~Nain()
{}

/**
 * Les  Nains ont +1 en Constitution et -1 en Charisme.
 * @param tab traits du personnage
 */
void Nain::appliquer_ajustements(unsigned int tab[6])
{
  tab[2]++;
  tab[5]--;
}

// /**
//  * Affiche la race et les capacités
//  */
// void Nain::affiche_info(ostream& os)
// {
//   os << "Race : " << Type << endreq;
//   for (unsigned int i(0); i<capacites.size(); i++)
//     os << Liste[capacites[i]].Capa << endreq;
// }

// /**
//  * Retrouve la capacité voulue.
//  * @param i le numéro de la capacité
//  * @return la capacité (string)
//  */
// string Nain::get_capacite(const unsigned int& i) const
// {
//   return Liste[get_capa(i)].Capa;
// }

// void Nain::get_capacites(unsigned int& nbr, vector<ListCapa> &capa) const
// {
//   nbr = taille;

//   capa.clear();

//   for (unsigned int i(0); i < taille; i++)
//     capa.push_back(Liste[i]);
// }

// void Nain::get_ensemble_racial(unsigned int& nbr, unsigned int& max) const
// {
//   nbr = ens;
//   max = nbr_comp;
// }

// const unsigned int* Nain::get_ensemble_racial(const unsigned int& nbr) const
// {
//   return &ensemble_racial[nbr][0];
// }
